package com.blackcat.dynamicexcel.service;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.blackcat.dynamicexcel.dao.ExcelHeaderDao;
import com.blackcat.dynamicexcel.dao.ExcelSheetDao;
import com.blackcat.dynamicexcel.dao.ExcelTemplateDao;
import com.blackcat.dynamicexcel.demo.vo.ExcelFrontEndParameter;
import com.blackcat.dynamicexcel.entity.*;
import com.blackcat.dynamicexcel.utils.BeanUtil;
import com.blackcat.dynamicexcel.utils.DynamicExcelUtil;
import com.blackcat.dynamicexcel.utils.UnderlineToCamelUtils;
import com.blackcat.dynamicexcel.vo.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.blackcat.dynamicexcel.utils.DynamicExcelUtil.getExcelSheetHandleData;

/**
 * 描述 ：动态导出excel
 *
 * @author : zhangdahui
 * @date : 2022/10/11 9:53
 */
@Service
public class DynamicExcelService {

    @Autowired
    private ExcelTemplateDao excelDao;
    @Autowired
    private ExcelSheetDao sheetDao;
    @Autowired
    private ExcelHeaderDao headerDao;

    /**
     * excel配置导出
     * @author : zhanghui
     * @cteateTime : 2023/11/29 16:09
     * @param excelId 模板ID，空则导出所有
     */
    public String configurationExport(String excelId) {
        List<ExcelTemplate> list = new ArrayList<>();
        if (StringUtils.isNotBlank(excelId)) {
            ExcelTemplate excel = excelDao.selectById(excelId);
            getTemplateInfo(excel);
            list.add(excel);
        }else {
            list = excelDao.selectList(null);
            if (CollectionUtils.isNotEmpty(list)) {
                list.forEach(excel -> getTemplateInfo(excel));
            }
        }
        return JSONArray.toJSONString(list);
    }

    private ExcelTemplate getTemplateInfo(ExcelTemplate excel){
        QueryWrapper<ExcelSheet> sheetQueryWrapper = new QueryWrapper<>();
        sheetQueryWrapper.eq("excel_id", excel.getId());
        List<ExcelSheet> excelSheets = sheetDao.selectList(sheetQueryWrapper);
        if (CollectionUtils.isNotEmpty(excelSheets)) {
            excelSheets.forEach(s -> {
                QueryWrapper<ExcelHeader> headerQueryWrapper = new QueryWrapper<>();
                headerQueryWrapper.eq("sheet_id", s.getId());
                s.setHeaders(headerDao.selectList(headerQueryWrapper));
            });
            excel.setSheets(excelSheets);
        }
        return excel;
    }


    /**
     * 描述 : 动态导出
     * @author : zhangdahui
     * @date : 2022/10/10 17:13
     * @param parameter 导出参数配置
     */
    public void dynamicExport(ExcelFrontEndParameter parameter) throws IOException {
        ExcelTemplate excelTemplate = excelDao.selectById(parameter.getExcelId());
        QueryWrapper<ExcelSheet> sheetQueryWrapper = new QueryWrapper<>();
        sheetQueryWrapper.eq("excel_id", parameter.getExcelId());
        List<ExcelSheet> excelSheets = sheetDao.selectList(sheetQueryWrapper);
        if (excelTemplate != null) {
            InputStream inputStream = this.getClass().getResourceAsStream(parameter.getExportTemplatePath());
            HSSFWorkbook wb = new HSSFWorkbook(inputStream);
            for (ExcelSheet excelSheet : excelSheets) {
                QueryWrapper<ExcelHeader> headerQueryWrapper = new QueryWrapper<>();
                headerQueryWrapper.eq("excel_id", parameter.getExcelId());
                headerQueryWrapper.eq("sheet_id", excelSheet.getId());
                List<ExcelHeader> excelHeaders = headerDao.selectList(headerQueryWrapper);
                excelSheet.setHeaders(excelHeaders);
                HSSFSheet codeSheet = wb.getSheetAt(excelSheet.getSheetIndex());
                if (CollectionUtils.isNotEmpty(parameter.getExcelSheetDataList())){
                    ExcelSheetData sheetData = null;
                    for (ExcelSheetData sheet : parameter.getExcelSheetDataList()) {
                        if (sheet.getSheetId().equals(excelSheet.getId())){
                            sheetData = sheet;
                            break;
                        }
                    }
                    if (sheetData != null) {
                        getSheet(codeSheet, excelSheet.getHeaderRow() + 1, excelHeaders, sheetData, parameter.isCamel(), parameter.isMultipleSub());
                    }
                }
            }
            HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            DynamicExcelUtil.downLoadExcel(parameter.getFileName(), response, wb);
        }
    }

    /**
     * 描述 : 填充sheet页数据
     * @author : zhangdahui
     * @date : 2022/10/10 17:13
     * @param sheet 代码页对象
     * @param startRow 数据起始行
     * @param headers 表头
     * @param excelSheetData 数据
     * @param camel 字段名称是否驼峰格式
     * @param multipleSub 是否多行子表
     */
    public void getSheet(HSSFSheet sheet,int startRow, List<ExcelHeader> headers, ExcelSheetData excelSheetData,boolean camel,boolean multipleSub){
        List<ExcelRowData> list = excelSheetData.getExportList();
        if (CollectionUtils.isNotEmpty(list)) {
            AtomicInteger rowIndex = new AtomicInteger(startRow);
            list.forEach(i->{
                Map<String, Object> masterData = i.getMasterExportData();
                HSSFRow row = sheet.createRow(rowIndex.get());
                setCellValue(headers,masterData,row,camel);
                if (multipleSub){
                    List<Map<String, Object>> sublistExportDataList = i.getSublistExportDataList();
                    if (CollectionUtils.isNotEmpty(sublistExportDataList)){
                        int sub = 0;
                        for (Map<String, Object> objectMap : sublistExportDataList) {
                            if (sub != 0) {
                                rowIndex.getAndIncrement();
                                HSSFRow rowSub = sheet.createRow(rowIndex.get());
                                setCellValue(headers, objectMap, rowSub, camel);
                            } else {
                                setCellValue(headers, objectMap, row, camel);
                            }
                            sub++;
                        }
                    }
                }
                rowIndex.getAndIncrement();
            });
        }
    }

    /**
     * 填充单元格内容
     * @author : zhanghui
     * @since : 2023/1/10 17:09
     * @param headers 所有表头定义
     * @param objectMap 对象 Map
     * @param row 当前行
     * @param camel 字段是否驼峰格式
    */
    private void setCellValue(List<ExcelHeader> headers,Map<String,Object> objectMap,HSSFRow row,boolean camel){
        headers.forEach(subHeader -> {
            String fileName = subHeader.getFieldName();
            if (camel){
                fileName = UnderlineToCamelUtils.underlineToCamel(fileName, true);
            }
            String value = mapGetValue(objectMap, fileName);
            if (StringUtils.isNotBlank(value)){
                HSSFCell cell = row.createCell(subHeader.getHeaderIndex());
                cell.setCellValue(value);
            }
        });
    }

    /**
     *  获取map值 处理空指针问题
     * @author : zhanghui
     * @since : 2023/1/10 17:09
     * @param map map
     * @param key 获取key
    */
    public static String mapGetValue(Map map,String key){
        if(map.get(key)!=null){
            return map.get(key).toString();
        }
        return "";
    }


    /**
     * 动态导入
     * @author : zhanghui
     * @since : 2023/1/3 11:22
     * @param file Excel
     * @param excelId Excel模板ID
     * @param additionalParam 额外参数，重写方法时使用
     */
    public Integer dynamicImport(MultipartFile file, int excelId,Map<String,Object> additionalParam) throws IOException {
        // 1. 获取工作簿
        Workbook workbook = DynamicExcelUtil.getWorkBook(file);
        // 2. 在数据库中获取Excel模板
        ExcelTemplate excelTemplate = excelDao.selectById(excelId);
        QueryWrapper<ExcelSheet> sheetQueryWrapper = new QueryWrapper<>();
        sheetQueryWrapper.eq("excel_id", excelId);
        List<ExcelSheet> excelSheets = sheetDao.selectList(sheetQueryWrapper);
        if (excelTemplate != null) {
            for (ExcelSheet excelSheet : excelSheets) {
                // 获取该 sheet 数据
                if (excelSheet.isData()){
                    // 3. 在数据库中获取Excel模板对应的表头信息
                    QueryWrapper<ExcelHeader> headerQueryWrapper = new QueryWrapper<>();
                    headerQueryWrapper.eq("excel_id", excelId);
                    headerQueryWrapper.eq("sheet_id", excelSheet.getId());
                    List<ExcelHeader> excelHeaders = headerDao.selectList(headerQueryWrapper);
                    excelSheet.setHeaders(excelHeaders);
                    // 4. 校验模板是否正确
                    Sheet sheet = workbook.getSheetAt(excelSheet.getSheetIndex());
                    Row row = sheet.getRow(excelSheet.getHeaderRow());
                    if (!DynamicExcelUtil.checkHeader(row, excelHeaders)) {
                        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
                        response.setContentType("text/plain");
                        response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode("错误详情", String.valueOf(StandardCharsets.UTF_8)) + ".txt");
                        OutputStream out = response.getOutputStream();
                        out.write((excelSheet.getSheetName() + "模板不正确！").getBytes(StandardCharsets.UTF_8));
                        return null;
                    }
                }
            }
            excelTemplate.setSheets(excelSheets);
            // 5. 所有枚举集合  key：枚举类型  value：枚举 Map
            Map<String, Map<String, String>> translateCodeMap = getTranslateCodeMap(excelSheets);
            // 6. 获取Excel数据
            List<SheetData> excelSheetData = DynamicExcelUtil.getExcelSheetData(excelTemplate, workbook);
            // 7. 校验数据
            List<SheetData> checkResult = checkExcelSheetData(excelSheetData, translateCodeMap,additionalParam);
            int errorCount = 0;
            int successCount = 0;
            for (SheetData sheetData : checkResult) {
                errorCount +=sheetData.getErrorList().size();
                successCount +=sheetData.getSuccessList().size();
            }
            // 处理异常信息
            if (errorCount > 0) {
                HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
                response.setContentType("text/plain");
                response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode("指标导入详情", String.valueOf(StandardCharsets.UTF_8)) + ".txt");
                OutputStream out = response.getOutputStream();
                StringBuffer errorText = new StringBuffer();
                errorText.append("本次一共上传");
                errorText.append(errorCount + successCount);
                errorText.append("条数据,其中");
                errorText.append(errorCount);
                errorText.append("条校验未通过，具体详细数据如下：\n");
                for (SheetData sheetData : checkResult) {
                    if (CollectionUtils.isNotEmpty(sheetData.getErrorList())){
                        errorText.append("========================== ").append(sheetData.getSheetName()).append(" 数据页异常信息 ==========================>\n");
                        // 根据行号排序
                        sheetData.getErrorList().sort((o1, o2) -> {
                            if (o1.getRow()<o2.getRow()) {
                                return -1;
                            }
                            return 0;
                        });
                        // 输出错误信息
                        for (ErrorRow errorRow : sheetData.getErrorList()) {
                            errorText.append("-------------- Excel 数据行，第").append(errorRow.getRow()+1).append("行 --------------\n");
                            errorText.append(errorRow.getErrorText());
                        }
                    }
                }
                errorText.append("请检查Excel数据内容!!!" + "\n");
                out.write(errorText.toString().getBytes(StandardCharsets.UTF_8));
                return null;
            }else {
                // 数据入库
               return saveDatabase(excelSheetData,additionalParam);
            }
        }
        return 300;
    }

    /**
     * 数据校验通过，保存数据，只做了主表简单逻辑入库处理。如有子表数据或复杂数据，请重写该方法。自定义入库写入。
     * @author : zhanghui
     * @since : 2023/1/6 17:50
     * @param sheetDataList Excel 处理后数据
    */
    public Integer saveDatabase(List<SheetData> sheetDataList,Map<String,Object> additionalParam) {
        if (CollectionUtils.isNotEmpty(sheetDataList)) {
            for (SheetData sheetData : sheetDataList) {
                List<RowData> rowData = sheetData.getSuccessList();
                if (CollectionUtils.isNotEmpty(rowData)) {
                    rowData.forEach(row -> {
                        System.out.println(row.getFields());
                    });
                }
            }
        }
        return 200;
    }

    /**
     * 给数据对象属性赋值
     * @author : zhanghui
     * @since : 2023/1/7 18:08
     * @param obj 数据对象
     * @param cellData 字段信息
    */
    public void objectSetValueByMap(Object obj,List<ExcelCellData> cellData) {
        Class c;
        c = obj.getClass();
        Field[] fields = c.getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
        }
        for (Field f : fields) {
            String field = f.toString().substring(f.toString().lastIndexOf(".") + 1);
            for (ExcelCellData data : cellData) {
                // 驼峰法转下划线
                String camelToUnderline = UnderlineToCamelUtils.camelToUnderline(field, false);
                if (data.getFieldName().equals(camelToUnderline)){
                    try {
                        if (StringUtils.isNotBlank(data.getTranslationValue())) {
                            BeanUtil.putAttr(obj,field, data.getTranslationValue());
                        }else {
                            BeanUtil.putAttr(obj,field, data.getCellValue());
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }

    /**
     * 校验 sheet 页数据
     * @author : zhanghui
     * @since : 2023/1/30 09:21
     * @param excelSheetDataList sheet 页数据
     * @param translateCodeMap 枚举信息
     * @param additionalParam 额外自定义参数
    */
    private List<SheetData> checkExcelSheetData(List<SheetData> excelSheetDataList,Map<String,Map<String,String>> translateCodeMap,Map<String,Object> additionalParam){
        for (SheetData excelSheetData : excelSheetDataList) {
            // 处理结果集合
            List<ErrorRow> errorList = new ArrayList<>(16);
            List<RowData> successList = new ArrayList<>(16);
            List<RowData> handleDataList = getExcelSheetHandleData(excelSheetData);
            // 校验数据
            if (CollectionUtils.isNotEmpty(handleDataList)){
                for (RowData row : handleDataList) {
                    AtomicBoolean flag = new AtomicBoolean(true);
                    List<ExcelCellData> cells = row.getCells();
                    // 主表
                    if (CollectionUtils.isNotEmpty(cells)){
                        StringBuffer errorText = new StringBuffer();
                        cells.forEach(c-> checkExcelCellData(c, translateCodeMap, errorText, additionalParam));
                        if (errorText.length() > 0) {
                            setErrorList(errorList, row.getRow(), errorText);
                            flag.set(false);
                        }
                    }
                    if (row.getGroupList() != null) {
                        Map<String, List<RowDataSubObject>> subGroup = row.getGroupList();
                        for (Map.Entry<String, List<RowDataSubObject>> entry : subGroup.entrySet()) {
                            List<RowDataSubObject> subObjectList = entry.getValue();
                            if (CollectionUtils.isNotEmpty(subObjectList)){
                                if (CollectionUtils.isNotEmpty(subObjectList)){
                                    subObjectList.forEach(sc->{
                                        List<ExcelCellData> cellDataList = sc.getCells();
                                        if (CollectionUtils.isNotEmpty(cellDataList)){
                                            StringBuffer errorText = new StringBuffer();
                                            cellDataList.forEach(c-> checkExcelCellData(c, translateCodeMap, errorText, additionalParam));
                                            if (errorText.length() > 0) {
                                                setErrorList(errorList, sc.getRow(), errorText);
                                                flag.set(false);
                                            }
                                        }
                                    });
                                }
                            }
                        }
                    }
                    StringBuffer errorText = new StringBuffer();
                    supplementCustomRowCheck(row, translateCodeMap, errorText, additionalParam);
                    if (errorText.length() > 0) {
                        setErrorList(errorList, row.getRow(), errorText);
                        flag.set(false);
                    }
                    if (flag.get()){
                        // 替换码表枚举值
                        Map<String, String> fields = row.getFields();
                        row.getCells().forEach(cell -> {
                            if (StringUtils.isNotBlank(cell.getTranslationValue())) {
                                fields.put(cell.getFieldName(), cell.getTranslationValue());
                            }
                        });
                        row.setFields(fields);
                        successList.add(row);
                    }
                }
            }
            excelSheetData.setSuccessList(successList);
            excelSheetData.setErrorList(errorList);
        }
        return excelSheetDataList;
    }


    private void setErrorList(List<ErrorRow> list,Integer row,StringBuffer errorText){
        if (list.stream().anyMatch(item -> item.getRow().equals(row))) {
            for (ErrorRow e : list) {
                if (e.getRow().equals(row)){
                    e.setErrorText(e.getErrorText().append(errorText));
                    break;
                }
            }
        } else {
            ErrorRow rowDataError = new ErrorRow();
            rowDataError.setRow(row);
            rowDataError.setErrorText(errorText);
            list.add(rowDataError);
        }
    }

    /**
     * 补充据校验：单元格校验
     *   需要增加自定义验证时，重写改方法
     * @author : zhanghui
     * @since : 2023/1/9 19:32
     * @param cell 单元格
     * @param translateCodeMap 枚举信息
     * @param errorText 错误信息
     * @param additionalParam 额外参数
    */
    public void supplementCustomCellCheck(ExcelCellData cell,Map<String,Map<String,String>> translateCodeMap,StringBuffer errorText,Map<String,Object> additionalParam){

    }

    /**
     * 补充据校验：行校验。需要多个单元格同时校验时需要。
     *   需要增加自定义验证时，重写改方法
     * @author : zhanghui
     * @since : 2023/1/9 19:32
     * @param row 行数据
     * @param translateCodeMap 枚举信息
     * @param errorText 错误信息
    */
    public void supplementCustomRowCheck(RowData row, Map<String,Map<String,String>> translateCodeMap, StringBuffer errorText, Map<String,Object> additionalParam){

    }

    /**
     * 校验单元格数据是否正确
     * @author : zhanghui
     * @since : 2023/1/6 10:50
     * @param cell 单元格数据
     * @param translateCodeMap 枚举信息
     * @param errorText 错误信息
     */
    private void checkExcelCellData(ExcelCellData cell,Map<String,Map<String,String>> translateCodeMap,StringBuffer errorText,Map<String,Object> additionalParam){
        // 是否必填 1：必填  0：不必填
        if (cell.isRequired()) {
            if (StringUtils.isBlank(cell.getCellValue())) {
                errorText.append("【").append(cell.getHeaderName()).append("】列：").append("不能为空；\n");
            }
        }
        // 是否验重 1：校验数据库中是否有重复  0：不校验是否有重复
        if (cell.isRepeat()) {
            if (StringUtils.isNotBlank(cell.getCellValue())){
                String repeatSql = cell.getTableName() + " where " + cell.getFieldName() + " = '" + cell.getCellValue() + "'";
                String repeatCount = excelDao.executeDynamicRepeatSQL(repeatSql);
                if (Integer.parseInt(repeatCount) > 0) {
                    errorText.append("【").append(cell.getHeaderName()).append("】列：")
                            .append("“").append(cell.getCellValue()).append("“").append("数据库中已存在；\n");
                }
            }
        }
        // 翻译代码
        if (StringUtils.isNotBlank(cell.getTranslateCode())) {
            Map<String, String> codeMap = translateCodeMap.get(cell.getTranslateCode());
            if (cell.isMultiple()){// 多个值枚举值
                String[] split = cell.getCellValue().split(",");
                StringJoiner stringJoiner = new StringJoiner(",");
                StringBuilder et = new StringBuilder();
                for (String val : split) {
                    if (codeMap.get(val) == null) {
                        et.append("　“").append(val).append("“ ").append("枚举填写不正确；");
                    }else {
                        stringJoiner.add(codeMap.get(val));
                    }
                }
                if (et.length() > 0) {
                    errorText.append("【").append(cell.getHeaderName()).append("】列：").append(et).append("\n");
                }
                cell.setTranslationValue(stringJoiner.toString());
            }else {// 单个枚举值
                if (codeMap.get(cell.getCellValue()) == null) {
                    errorText.append("【").append(cell.getHeaderName()).append("】列：")
                            .append("“").append(cell.getCellValue()).append("“ ").append("枚举填写不正确；\n");
                } else {
                    cell.setTranslationValue(codeMap.get(cell.getCellValue()));
                }
            }
        }
        // 补充自定义验证
        supplementCustomCellCheck(cell,translateCodeMap,errorText,additionalParam);
    }


    /**
     * 补充自定义枚举信息
     * @author : zhanghui
     * @since : 2023/1/16 17:05
     * @param translateCodeMap 通用枚举信息
    */
    public Map<String, Map<String, String>> supplementTranslateCodeMap(Map<String, Map<String, String>> translateCodeMap) {
        return translateCodeMap;
    }

    /**
     * 获取所有需要翻译的枚举信息
     * @author : zhanghui
     * @since : 2023/1/3 16:04
     * @param excelSheets 数据页
    */
    private Map<String, Map<String, String>> getTranslateCodeMap(List<ExcelSheet> excelSheets){
        // 通用枚举表 例如：代码配置表
        List<TranslateEnum> commEnumList = new ArrayList<>();
        // 独立枚举表 例如：用户、部门表
        List<TranslateEnum> singleEnumList = new ArrayList<>();
        // 所有枚举集合  key：枚举类型或表名  value：枚举 Map
        Map<String, Map<String, String>> translateCodeMap = new HashMap<>(16);
        excelSheets.forEach(sheet->{
            if (CollectionUtils.isNotEmpty(sheet.getHeaders())){
                for (ExcelHeader excelHeader : sheet.getHeaders()) {
                    if (StringUtils.isNotBlank(excelHeader.getTranslateTable())){
                        TranslateEnum code = new TranslateEnum();
                        BeanUtils.copyProperties(excelHeader, code);
                        if (StringUtils.isNotBlank(excelHeader.getTranslateCode())) {
                            if (commEnumList.stream().noneMatch(c -> excelHeader.getTranslateCode().equals(c.getTranslateCode()) && excelHeader.getTranslateTable().equals(c.getTranslateTable()))) {
                                commEnumList.add(code);
                            }
                        } else {
                            if (commEnumList.stream().noneMatch(c->excelHeader.getTranslateTable().equals(c.getTranslateTable()))){
                                singleEnumList.add(code);
                            }
                        }
                    }
                }
            }
        });
        // 整理枚举信息
        if (CollectionUtils.isNotEmpty(commEnumList)) {
            commEnumList.forEach(e->{
                List<Map<String, String>> list = excelDao.queryCodeTableByCondition(e.getTranslateMeaning(), e.getTranslateValue(), e.getTranslateTable(), e.getTranslateCodeField(), e.getTranslateCode());
                if (CollectionUtils.isNotEmpty(list)) {
                    Map<String, String> map = new HashMap<>(16);
                    list.forEach(i -> map.put(i.get(e.getTranslateMeaning()), i.get(e.getTranslateValue())));
                    translateCodeMap.put(e.getTranslateCode(), map);
                }
            });
        }
        if (CollectionUtils.isNotEmpty(singleEnumList)) {
            singleEnumList.forEach(e->{
                List<Map<String, String>> list = excelDao.queryCodeTable(e.getTranslateMeaning(), e.getTranslateValue(), e.getTranslateTable());
                if (CollectionUtils.isNotEmpty(list)) {
                    Map<String, String> map = new HashMap<>(16);
                    list.forEach(i -> map.put(i.get(e.getTranslateMeaning()), i.get(e.getTranslateValue())));
                    translateCodeMap.put(e.getTranslateTable(), map);
                }
            });
        }
//        System.out.println("translateCodeMap " + translateCodeMap);
        supplementTranslateCodeMap(translateCodeMap);
        return translateCodeMap;
    }


}
